#include "gdbinfo.h"
#include "xethernet.h"
#include "xarp.h"
#include "xip.h"

uint8_t my_mac[XNET_MAC_ADDR_SIZE];

xnet_err_t ethernet_init(void)
{
    xnet_err_t err = xnet_driver_open(my_mac);
    if (err < 0)
        return err;
    return XNET_ERR_OK;
};

void ethernet_poll(void)
{
    // 轮询，查看有没有收到网络包
    xnet_packet_t *packet;

    if (xnet_driver_read(&packet) == XNET_ERR_OK)
    {
        // 正常情况下，在此打个断点，全速运行
        // 然后在对方端ping 192.168.254.2，会停在这里
        ethernet_in(packet);
    }
}

static void ethernet_in(xnet_packet_t *packet)
{
    if ((GDB_INFO_SWITCH && ETHERNET_GDB_INFO))
        print_info("get a ethernet packet , size =0x%x", packet->size);

    xether_hdr_t *ether_hdr;
    uint16_t protocol;

    if (packet->size < sizeof(xether_hdr_t))
    {
        return;
    }

    ether_hdr = (xether_hdr_t *)packet->data;
    protocol = swap_order16(ether_hdr->protocal);

    switch (protocol)
    {
    case XNET_PROTOCOL_ARP:
        remove_header(packet, sizeof(xether_hdr_t));
        xarp_in(packet);
        break;
    case XNET_PROTOCOL_IP:

        remove_header(packet, sizeof(xether_hdr_t));
        xip_hdr_t *ip_hdr = (xip_hdr_t *)packet->data;
        update_arp_entry(ip_hdr->src_ip, ether_hdr->src);
        xip_in(packet);
        break;
    default:
        break;
    }
};
xnet_err_t ethernet_out_to(xnet_protocol_t protocol, const uint8_t *mac_addr, xnet_packet_t *packet)
{
    // 发送数据包，调用物理层的接口，需要mac地址
    xether_hdr_t *ether_hdr;
    // 加头目
    add_header(packet, sizeof(xether_hdr_t));
    ether_hdr = (xether_hdr_t *)packet->data;
    memcpy(ether_hdr->dest, mac_addr, XNET_MAC_ADDR_SIZE);
    memcpy(ether_hdr->src, my_mac, XNET_MAC_ADDR_SIZE);
    ether_hdr->protocal = swap_order16(protocol);

    if ((GDB_INFO_SWITCH && ETHERNET_GDB_INFO))
        print_info("try to send a ethernet packet , size =0x%x", packet->size);

    return xnet_driver_send(packet);
};

xnet_err_t ethernet_out(xnet_protocol_t protocol, const uint8_t *target_ip, xnet_packet_t *packet)
{
    // 在arp表单查询target_ip对应的mac，然后调用上面的接口，需要ip地址
    uint8_t *mac_addr; // 只是一个指针
    xnet_err_t err = xarp_resolve(target_ip, mac_addr);
    if (err == XNET_ERR_OK)
    {
        return ethernet_out_to(protocol, mac_addr, packet);
    }
    else
    {
        return err;
    }
};
